Skip to content

Introduce support for MSC4429: Profile Updates for Legacy Sync#19556

Open
anoadragon453 wants to merge 141 commits into
developfrom
anoa/msc4429
Open

Introduce support for MSC4429: Profile Updates for Legacy Sync#19556
anoadragon453 wants to merge 141 commits into
developfrom
anoa/msc4429

Conversation

@anoadragon453

@anoadragon453 anoadragon453 commented Mar 13, 2026

Copy link
Copy Markdown
Member

This PR implements support for MSC4429: Profile Updates for Legacy Sync.

Recommended to review commit-by-commit. Commit history has become messy, suggest reviewing as a single item.

Paired with matrix-org/complement#849 and branch https://github.com/matrix-org/sytest/tree/anoa/msc4429

Tracking issue for removing unstable identifiers in Synapse: #19891

Pull Request Checklist

  • Pull request is based on the develop branch
  • Pull request includes a changelog file. The entry should:
    • Be a short description of your change which makes sense to users. "Fixed a bug that prevented receiving messages from other servers." instead of "Moved X method from EventStore to EventWorkerStore.".
    • Use markdown where necessary, mostly for code blocks.
    • End with either a period (.) or an exclamation mark (!).
    • Start with a capital letter.
    • Feel free to credit yourself, by adding a sentence "Contributed by @github_username." or "Contributed by [Your Name]." to the end of the entry.
  • Code style is correct (run the linters)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements experimental MSC4429 support by introducing a new profile_updates stream (persisted + replicated) and surfacing profile field changes in legacy /sync when enabled.

Changes:

  • Add profile_updates stream tracking (DB schema, stream token field, notifier + replication stream plumbing).
  • Emit MSC4429 profile updates in /sync responses and add filter support for selecting profile fields.
  • Record profile field updates on profile mutations (set/unset displayname/avatar/custom fields, deactivation cleanup).

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/rest/client/test_rooms.py Updates hardcoded stream tokens to match the new StreamToken shape.
tests/rest/admin/test_room.py Updates hardcoded stream tokens to match the new StreamToken shape.
synapse/types/init.py Adds PROFILE_UPDATES stream key and extends StreamToken serialization/parsing.
synapse/streams/events.py Includes profile_updates_key in current/bounded stream tokens.
synapse/storage/schema/main/delta/94/01_profile_updates_seq.sql.postgres Adds Postgres sequence for the new stream.
synapse/storage/schema/main/delta/94/01_profile_updates.sql Adds profile_updates table + indexes.
synapse/storage/schema/init.py Bumps schema version to 94 and documents the change.
synapse/storage/databases/main/profile.py Adds profile update persistence/query APIs and stream ID generator wiring.
synapse/rest/client/versions.py Advertises org.matrix.msc4429 in unstable_features.
synapse/rest/client/sync.py Encodes MSC4429 profile update payload into /sync response.
synapse/replication/tcp/streams/_base.py Adds ProfileUpdatesStream replication stream.
synapse/replication/tcp/streams/init.py Registers ProfileUpdatesStream for replication.
synapse/replication/tcp/handler.py Replicates ProfileUpdatesStream from configured writers.
synapse/replication/tcp/client.py Handles incoming profile update replication and notifies listeners.
synapse/notifier.py Allows StreamKeyType.PROFILE_UPDATES to wake /sync waiters.
synapse/handlers/sync.py Generates initial + incremental MSC4429 profile update sections in /sync.
synapse/handlers/profile.py Records profile update markers on profile mutations and notifies.
synapse/config/experimental.py Adds msc4429_enabled config flag.
synapse/api/filtering.py Adds /sync filter support for selecting profile fields (MSC4429-gated).
docker/complement/conf/workers-shared-extra.yaml.j2 Enables MSC4429 in complement worker test config.
changelog.d/19556.feature Adds changelog entry for MSC4429 experimental support.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread synapse/replication/tcp/client.py Outdated
Comment thread synapse/storage/schema/main/delta/94/01_profile_updates.sql Outdated
Comment thread synapse/storage/databases/main/profile.py Outdated
Comment thread synapse/handlers/sync.py Outdated
@anoadragon453 anoadragon453 force-pushed the anoa/msc4429 branch 2 times, most recently from 83e699f to a846945 Compare March 17, 2026 16:21
anoadragon453 added a commit to matrix-org/sytest that referenced this pull request Mar 17, 2026
anoadragon453 added a commit to matrix-org/sytest that referenced this pull request Mar 17, 2026
@anoadragon453 anoadragon453 marked this pull request as ready for review March 18, 2026 15:58
@anoadragon453 anoadragon453 requested a review from a team as a code owner March 18, 2026 15:58
We create a stream table dedicated to tracking profile updates. The sync
machinary can this stream to understand whether a profile update
needs to be included in a client's sync response.
Add a new stream type for profile updates. This allows sync processes to
determine which profile updates a given user has or hasn't seen yet.
Replicate changes to the profile updates stream so that sync workers
know there's a new profile update, and wake up sync waiters accordingly.

Updates are keyed by `room_id` - sync waiters should only wake up if
a user they share a room with updates their profile.
Based on the provided since token and filter.
And update relevant documentation/integration test config.
Prevent the `ProfileRestServlet` from handling requests intended for the
`ProfileFieldRestServlet`.

If a requester tried to call PUT `.../profile/@user:domain/(key_id?)` a
worker that did not mount `ProfileFieldRestServlet`, they would then
receive a `405 Method Not Allowed` instead of the expected `404 Not
Found`.
Comment thread docs/upgrade.md Outdated
Comment thread synapse/handlers/sync.py Outdated
Comment thread synapse/handlers/sync.py Outdated
jaywink added 4 commits July 6, 2026 15:08
… leave

Regardless of action. This is cleaner and also ensures a join/leave/join/leave case might not get confused.
…oined profile updates rows, due to membership event changes
Comment thread synapse/handlers/sync.py
Comment thread synapse/handlers/sync.py Fixed
jaywink and others added 17 commits July 6, 2026 18:42
To make CI happier, even though we just want to compare content has changed.
Extracted to a follow-up pr.

This reverts commit b657d2f
Setting a profile field (including displayname / avatar_uri) now needs to happen on a profile updates stream writer. There are new "dispatch" methods to do the profile field set/delete, that handle pushing the update over replication, if required.

Profile field updates and profile updates stream writes are now in the same database transaction.
…ile fields, to update the profile updates stream"

This reverts commit 1937e76.
I changed things so deactivation did call these and no tests failed.
We now do all the actions relating to the stream updates in one transaction.

Additionally ensure we wake up the notifier for the users concerned.
…rofile updates stream updates in a single transaction
# Conflicts:
#	synapse/rest/client/versions.py
@jaywink jaywink requested review from dbkr and reivilibre July 8, 2026 10:23
@jaywink

jaywink commented Jul 8, 2026

Copy link
Copy Markdown
Member

I think this is ready for another round of review 🙏 A big thanks @reivilibre for all the detail in the previous reviews.

There is one unresolved comment: #19556 (comment) - I'm unsure what is the right way to go here, but have suggested my favourite option I could come up with.

jaywink added 3 commits July 8, 2026 15:15
Replication path arguments need to be strings.
Since we moved a lot of stuff to happen in the profile update stream writers, we need to always have the replication endpoints enabled now.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants